package com.jplus.mvc.action;

import java.util.HashMap;
import java.util.Map;

import com.jplus.core.anno.com.Autowired;
import com.jplus.core.mvc.WebUtil;
import com.jplus.core.mvc.anno.PathVariable;
import com.jplus.core.mvc.anno.RequestMapping;
import com.jplus.core.mvc.anno.RequestParam;
import com.jplus.core.mvc.anno.RestController;
import com.jplus.core.mvc.vo.Model;
import com.jplus.core.utill.Assert;
import com.jplus.core.utill.JSON;
import com.jplus.core.utill.JUtil;
import com.jplus.core.utill.LRUCache;
import com.jplus.mvc.util.EncryptionUtil;
import com.jplus.mvc.util.UUIDUtil;

import io.lettuce.core.SetArgs;
import io.lettuce.core.SetArgs.Builder;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;

@RestController
public class IndexAction {

	// NXXX:只能取NX或者XX，NX-key不存在时进行保存，XX-key存在时才进行保存
	// EXPX:过期时间单位 (EX,PX)，EX-秒，PX-毫秒
	final SetArgs ttl = Builder.nx().ex(1L * 60L * 60L * 24L * 30L);// 30天
	final String domain = "http://clicli.ink";

	final LRUCache<String, String> cache = new LRUCache<>(1000);
	final int keyLen = 6;
	final String LP = "S_";

	private @Autowired StatefulRedisConnection<String, String> rediscon;

	@RequestMapping("/")
	public void hello() {
		Map<String, Object> map = new HashMap<>();
		map.put("version", "jplus 0.0.1");
		map.put("cache", cache.size());
		WebUtil.writeTEXT(JSON.format(JSON.toJSONString(new Model().SUCC().DATA(map))));
	}

	@RequestMapping("/restful/{msg}")
	public Model sayMsg(@PathVariable("msg") String msg) {
		return new Model().SUCC().DATA("Welcome  clicli.ink,say:" + msg);
	}

	/** 访问短链 */
	@RequestMapping("/s/{key}")
	public void shortUrlRedister(@PathVariable("key") String key) {
		Assert.isTrue(key != null && key.length() == keyLen, "Not the correct short link");
		String redisKey = LP + key;
		String longurl = cache.get(redisKey, (o1) -> {
			RedisCommands<String, String> sync = rediscon.sync();
			return sync.get(o1);
		});
		if (longurl != null)
			WebUtil.redirectRequest(longurl.toString());
		else
			WebUtil.writeJSON(new Model().FAIL().DATA("The target domain name does not exist or has expired"));
	}

	/** 生成短链 */
	@RequestMapping("/s/build")
	public Model shortUrl(@RequestParam("url_long") String longUrl) {
		Assert.isTrue(longUrl.length() >= 10 && longUrl.substring(0, 4).equalsIgnoreCase("HTTP"),
				"The original connection url is malformed");
		String hash = EncryptionUtil.getHash(longUrl, "MD5");
		String hx = hash.substring(8, 16);
		long x = UUIDUtil.parseLong10(hx, 16);
		String key = JUtil.leftPad(UUIDUtil.parseStrJZ(x, 62), keyLen, "Z");
		// =============================================
		String redisKey = LP + key;
		if (cache.get(redisKey) == null) {
			RedisCommands<String, String> rcmd = rediscon.sync();
			rcmd.set(redisKey, longUrl, ttl);
			cache.put(redisKey, longUrl);
		}
		// ==============================================
		Map<String, String> res = new HashMap<>();
		res.put("url_short", domain + "/s/" + key);
		res.put("url_long", longUrl);
		return new Model().SUCC().DATA(res);
	}

}
